//
//  HMRefreshControl.swift
//  WeiBo
//
//  Created by Feng on 2017/6/11.
//  Copyright © 2017年 feng. All rights reserved.
//

import UIKit

//刷新状态:枚举类型
enum HMRefreshControlType
{
    //下拉刷新 --> 刷新视图没有走出临界边界,还在navigationBar里面
    case normal
    //松手刷新 --> 已经离开临界边界,手还没有松开
    case pulling
    //正在刷新 --> 刷新视图停留在临界边界下边,完了之后进入normal
    case refreshing
}

//设置控件的高度
private let HMRefreshControlHeight: CGFloat = 50

class HMRefreshControl: UIControl {
    
    //设置当前视图的初始状态
    var refreshControlType: HMRefreshControlType = .normal
    {
        didSet {
            switch refreshControlType {
            case .normal:
                //显示下拉箭头,停止风火轮,重置箭头,显示"下拉刷新"
                pullDownImageView.isHidden = false
                indicatiorView.stopAnimating()
                messageLabel.text = "下拉刷新"
                UIView.animate(withDuration: 0.25, animations: { 
                    self.pullDownImageView.transform = CGAffineTransform.identity
                }, completion: { (_) in
                    
                    //didSet中旧值是oldValue, set中新值是newValue
                    if oldValue == .refreshing
                    {
                        UIView.animate(withDuration: 0.25, animations: { 
                            self.currentScrollView!.contentInset.top -= HMRefreshControlHeight
                        })
                    }
                })
            case .pulling:
                //箭头倒转,显示"松手就刷新"
                messageLabel.text = "松手就刷新"
                UIView.animate(withDuration: 0.25, animations: { 
                    self.pullDownImageView.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
                })
            case .refreshing:
                //启动风火轮,隐藏箭头,显示"正在刷新"
                pullDownImageView.isHidden = true
                indicatiorView.startAnimating()
                messageLabel.text = "正在刷新"
                UIView.animate(withDuration: 0.25, animations: { 
                    //设置停留位置
                    self.currentScrollView!.contentInset.top += HMRefreshControlHeight
                }, completion: { (_) in
                    
                })
                
                sendActions(for: .valueChanged)
            }
        }
    }
    
    //定义当前滚动的视图
    var currentScrollView: UIScrollView?
    
    //MARK: --懒加载控件
    //向下箭头
    private lazy var pullDownImageView: UIImageView =
    {
        let imageView = UIImageView()
        
        imageView.image = UIImage(named: "tableview_pull_refresh")
        
        return imageView
    }()
    //提示信息
    private lazy var messageLabel: UILabel =
    {
        let label = UILabel(fontSize: 14, textColor: UIColor.gray)
        
        label.text = "下拉刷新"
        
        return label
    }()
    //风火轮
    private lazy var indicatiorView: UIActivityIndicatorView =
    {
        let indicatiorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
        
        indicatiorView.startAnimating()
        
        return indicatiorView
    }()

    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //MARK: --添加控件,设置约束
    private func setupUI()
    {
        addSubview(pullDownImageView)
        addSubview(messageLabel)
        addSubview(indicatiorView)
        
        //设置约束
        pullDownImageView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        indicatiorView.translatesAutoresizingMaskIntoConstraints = false
        
        addConstraint(NSLayoutConstraint(item: pullDownImageView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: -38))
        addConstraint(NSLayoutConstraint(item: pullDownImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .leading, relatedBy: .equal, toItem: pullDownImageView, attribute: .trailing, multiplier: 1, constant: 2))
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: indicatiorView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: -38))
        addConstraint(NSLayoutConstraint(item: indicatiorView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        
        backgroundColor = UIColor.red
    }
    
    override func willMove(toSuperview newSuperview: UIView?) {
        
        if newSuperview is UIScrollView
        {
            let scrollView = newSuperview as! UIScrollView
            
            //使用kvo监听视图的滚动距离
            scrollView.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.new, context: nil)
            
            frame.size.width = UIScreen.main.bounds.width
            frame.size.height = HMRefreshControlHeight
            //设置origin.y向上偏移
            frame.origin.y = -HMRefreshControlHeight
            
            currentScrollView = scrollView
        }
    }
    
    //MARK: --kvo监听方法
    //  keypath： 监听属性
    //  object:   监听属性对应的对象
    //  change:  获取监听参数比如可以通过字典获取（最新）的滚动偏移量
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

        //根据视图偏移距离,判断下拉视图的状态 --> 1.normal 2.pull 3.refresh
        //视图的偏移量
        let contentOffsetY = currentScrollView!.contentOffset.y
        
//        print("contentOffsetY\(contentOffsetY)")
        
        if currentScrollView!.isDragging
        {
            //临界偏移量
            let limitOffsetY = -(currentScrollView!.contentInset.top + HMRefreshControlHeight)
//            print("limitOffsetY\(limitOffsetY)")
            
            if contentOffsetY < limitOffsetY && refreshControlType == .normal
            {
                //normal-->pulling状态
                refreshControlType = .pulling
                
                print("pulling")
            }
            else if contentOffsetY >= limitOffsetY && refreshControlType == .pulling
            {
                //从pulling-->normal
                refreshControlType = .normal
                print("normal")
            }
        }
        else if refreshControlType == .pulling
        {
            //pulling --> refreshing
            refreshControlType = .refreshing
            print("refreshing")
        }
    }
    
    //MARK: --结束刷新
    func endRefreshing()
    {
        refreshControlType = .normal
    }
    
    deinit {
        //移除kvo
        currentScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
}
